package cn.xiyun.xiyuncc.service.impl;

import cn.xiyun.xiyuncc.domain.CourseType;
import cn.xiyun.xiyuncc.mapper.CourseTypeMapper;
import cn.xiyun.xiyuncc.service.ICourseTypeService;
import cn.xiyun.xiyuncc.util.AssertUtil;
import cn.xiyun.xiyuncc.vo.CourseTypeVO;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 课程目录 服务实现类
 * </p>
 *
 * @author xiyun.maple
 * @since 2023-03-11
 */
@Service
public class CourseTypeServiceImpl extends ServiceImpl<CourseTypeMapper, CourseType> implements ICourseTypeService {
    /**
     * 课程类型树KEY
     */
    private static final String TREE_DATA_KEY = "COURSE_TYPE_TREE_DATA";

    @Autowired
    private CourseTypeMapper courseTypeMapper;
    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;


    /**
     * 面包屑
     * @param id
     * @return
     */
    @Override
    public List<CourseTypeVO> crumbsData(Long id) {
        // 返回的list集合
        List<CourseTypeVO> courseTypeVOList = new ArrayList<>();
        // 查询
        CourseType courseTypeOne = super.selectById(id);
        AssertUtil.isNotNull(courseTypeOne,"当前类型不存在");
        // 根据path分词
        String path = courseTypeOne.getPath();
        List<String> split= Arrays.asList(path.split("\\."));
        // 查询全部path
        List<CourseType> pTypes = super.selectBatchIds(split);
        System.out.println(pTypes);
        // 查询全部
        List<CourseType> courseTypes = super.selectList(null);
        pTypes.forEach(courseType->{
            CourseTypeVO courseTypeVO = new CourseTypeVO();
            // 将CourseType放入OwnerProductType
            courseTypeVO.setOwnerProductType(courseType);
            // List存放Pid相同的CourseType
            List<CourseType> types= new ArrayList<>();
            courseTypes.forEach(PCourseType -> {
                // 遍历courseTypes集合查询Pid相同的放入list集合中
                if (PCourseType.getPid().equals(courseType.getPid())) {
                    types.add(PCourseType);
                }
            });
            courseTypeVO.setOtherProductTypes(types);
            courseTypeVOList.add(courseTypeVO);
        });
        return courseTypeVOList;

    }



    @Override
    @Cacheable(cacheNames = TREE_DATA_KEY)
    public List<CourseType> treeData() {
        // List<CourseType> treeList = new ArrayList<>();
        List<CourseType> treeList = (List<CourseType>) redisTemplate.opsForValue().get(TREE_DATA_KEY);
        return getTree();
    }

    // 类型树
    private List<CourseType> getTree() {
        List<CourseType> treeList = new ArrayList<>();
        List<CourseType> courseTypes = courseTypeMapper.selectList(null);
        Map<Long, CourseType> courseTypeMap =
                courseTypes.stream().collect(Collectors.toMap(CourseType::getId, courseType -> courseType));
        for (CourseType courseType : courseTypes) {
            if (courseType.getPid() == null || courseType.getPid() == 0) {
                treeList.add(courseType);
            } else {
                courseTypeMap.get(courseType.getPid()).getChildren().add(courseType);
            }
        }
        redisTemplate.opsForValue().set(TREE_DATA_KEY, treeList);
        return treeList;
    }

    @Override
    public boolean insert(CourseType entity) {
        redisTemplate.delete(TREE_DATA_KEY);
        boolean insert = super.insert(entity);
        redisTemplate.delete(TREE_DATA_KEY);
        return insert;
    }

    @Override
    public boolean update(CourseType entity, Wrapper<CourseType> wrapper) {
        redisTemplate.delete(TREE_DATA_KEY);
        boolean update = super.update(entity, wrapper);
        redisTemplate.delete(TREE_DATA_KEY);
        return update;
    }

    @Override
    @CacheEvict(cacheNames= TREE_DATA_KEY)
    public boolean updateById(CourseType entity) {
        redisTemplate.delete(TREE_DATA_KEY);
        boolean b = super.updateById(entity);
        redisTemplate.delete(TREE_DATA_KEY);
        return b;
    }

    @Override
    public boolean deleteById(Serializable id) {
        redisTemplate.delete(TREE_DATA_KEY);
        boolean b = super.deleteById(id);
        redisTemplate.delete(TREE_DATA_KEY);
        return b;
    }
}
